Bug 314084 - GTK+ dialogs should not be placed partially offscreen
authorTor Lillqvist <tml@novell.com>
Thu, 20 Mar 2008 03:00:45 +0000 (03:00 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Thu, 20 Mar 2008 03:00:45 +0000 (03:00 +0000)
2008-03-20  Tor Lillqvist  <tml@novell.com>

Bug 314084 - GTK+ dialogs should not be placed partially offscreen

* gtk/gtkwindow.c (clamp): New function. Clamps a window position
in one dimension, or centered in case it doesn't fit.
(clamp_window_to_rectangle): Simplify. Call clamp() for x and y
dimensions.

svn path=/trunk/; revision=19907

ChangeLog
gtk/gtkwindow.c

index 064eeed5c3d59a618389c06bb05ad1bc44f1f853..8ee0c5c110835d8366ee8e6ab8f908dcee311bfb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-03-20  Tor Lillqvist  <tml@novell.com>
+
+       Bug 314084 - GTK+ dialogs should not be placed partially offscreen
+
+       * gtk/gtkwindow.c (clamp): New function. Clamps a window position
+       in one dimension, or centered in case it doesn't fit.
+       (clamp_window_to_rectangle): Simplify. Call clamp() for x and y
+       dimensions.
+
 2008-03-18  Tor Lillqvist  <tml@novell.com>
 
        Bug 523225 - modules/input/im*.c: MODULE_ENTRY macros make illegal code
index 04dc992f3bf7a6e0e359d2caea3b907ccefd69e8..27412221cbc906fc195e20013d7d8fb41bb3dbf6 100644 (file)
@@ -5516,6 +5516,21 @@ center_window_on_monitor (GtkWindow *window,
     *y = monitor.y;
 }
 
+static void
+clamp (gint *base,
+       gint  extent,
+       gint  clamp_base,
+       gint  clamp_extent)
+{
+  if (extent > clamp_extent)
+    /* Center */
+    *base = clamp_base + clamp_extent/2 - extent/2;
+  else if (*base < clamp_base)
+    *base = clamp_base;
+  else if (*base + extent > clamp_base + clamp_extent)
+    *base = clamp_base + clamp_extent - extent;
+}
+
 static void
 clamp_window_to_rectangle (gint               *x,
                            gint               *y,
@@ -5523,21 +5538,19 @@ clamp_window_to_rectangle (gint               *x,
                            gint                h,
                            const GdkRectangle *rect)
 {
-  gint outside_w, outside_h;
-  
-  outside_w = (*x + w) - (rect->x + rect->width);
-  if (outside_w > 0)
-    *x -= outside_w;
-
-  outside_h = (*y + h) - (rect->y + rect->height);
-  if (outside_h > 0)
-    *y -= outside_h; 
+#ifdef DEBUGGING_OUTPUT
+  g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", __FUNCTION__, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
+#endif
 
-  /* if larger than the screen, center on the screen. */
-  if (*x < rect->x)
-    *x += (rect->x - *x) / 2;
-  if (*y < rect->y)
-    *y += (rect->y - *y) / 2;
+  /* If it is too large, center it. If it fits on the monitor but is
+   * partially outside, move it to the closest edge. Do this
+   * separately in x and y directions.
+   */
+  clamp (x, w, rect->x, rect->width);
+  clamp (y, h, rect->y, rect->height);
+#ifdef DEBUGGING_OUTPUT
+  g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
+#endif
 }